#pragma once
#include<vector>
template <class T>
class Less
{
public:
	bool operator()(const T& a, const T& b)
	{
		return a < b;
	}
};
template <class T>
class Greater
{
	bool operator()(const T& a, const T& b)
	{
		return a>b;
	}
};
namespace zkf
{
	template<class T,class container=vector<T>,class com=Less<T>>
	class priority_queue
	{
	public:
		priority_queue()
		{

		}
		template<class inputiterator>
		priority_queue(inputiterator w1, inputiterator w2)
		{
			while (w1 != w2)
			{
				push(*w1);
				w1++;
			}
		}
		com qw;
		void adjustup(int child)
		{
			int parent= (child-1)/2;
			while (child > 0)
			{
				if (qw(_as[parent],_as[child]))
				{
					swap(_as[child], _as[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void push(const T& s)
		{
			_as.push_back(s);
			adjustup(_as.size()-1);
		}
		void adjustdown(int parent)
		{
			int child = parent * 2 + 1;
			while (child < _as.size())
			{
				if (child + 1 < _as.size()&&qw(_as[child] , _as[child + 1]) )
				{
					child++;
				}
				if (qw(_as[parent],_as[child]))
				{
					swap(_as[child], _as[parent]);
					parent= child;
					child = parent*2+1;
				}
				else
				{
					break;
				}
			}
		}
		void pop()
		{
			swap(_as[0], _as[_as.size() - 1]);
			_as.pop_back();
			adjustdown(0);
		}
		const T& top()const
		{
			return _as[0];
		}
		size_t size()const
		{
			return _as.size();
		}
		bool empty()const
		{
			return _as.size() == 0;
		}
		const T& operator[](size_t i)const
		{
			return _as[i];
		}
	private:
		container _as;
	};
}